[TPM] back: Allocate pages for foreign mappings individually rather than contiguously.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 5 Oct 2006 22:16:21 +0000 (23:16 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 5 Oct 2006 22:16:21 +0000 (23:16 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c

index 27b8fd283ad9c61dc4e11fd87e70e922cb85e354..b209b4f583e60dd77ef1e1d2a54666b7539b3627 100644 (file)
@@ -46,11 +46,10 @@ typedef struct tpmif_st {
        atomic_t refcnt;
 
        struct backend_info *bi;
-       unsigned long mmap_vstart;
 
        grant_handle_t shmem_handle;
        grant_ref_t shmem_ref;
-       struct page *pagerange;
+       struct page **mmap_pages;
 
        char devname[20];
 } tpmif_t;
@@ -80,6 +79,9 @@ int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
 
 extern int num_frontends;
 
-#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
+static inline unsigned long idx_to_kaddr(tpmif_t *t, unsigned int idx)
+{
+       return (unsigned long)pfn_to_kaddr(page_to_pfn(t->mmap_pages[idx]));
+}
 
 #endif /* __TPMIF__BACKEND__COMMON_H__ */
index 0105bd93bfb90d150b710cd7fd136cfbdb782d2c..ce06f7ce58855753e9576f9f765c149d4d63f375 100644 (file)
@@ -23,10 +23,11 @@ LIST_HEAD(tpmif_list);
 static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi)
 {
        tpmif_t *tpmif;
+       int i;
 
        tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
        if (!tpmif)
-               return ERR_PTR(-ENOMEM);
+               goto out_of_memory;
 
        memset(tpmif, 0, sizeof (*tpmif));
        tpmif->domid = domid;
@@ -35,22 +36,46 @@ static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi)
        snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
        atomic_set(&tpmif->refcnt, 1);
 
-       tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
-       BUG_ON(tpmif->pagerange == NULL);
-       tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(
-                                           page_to_pfn(tpmif->pagerange));
+       tpmif->mmap_pages = kmalloc(sizeof(tpmif->mmap_pages[0])
+                                   * TPMIF_TX_RING_SIZE, GFP_KERNEL);
+       if (tpmif->mmap_pages == NULL)
+               goto out_of_memory;
+
+       for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
+               tpmif->mmap_pages[i] = balloon_alloc_empty_page();
+               if (tpmif->mmap_pages[i] == NULL) {
+                       while (--i >= 0)
+                               balloon_free_empty_page(tpmif->mmap_pages[i]);
+                       goto out_of_memory;
+               }
+       }
 
        list_add(&tpmif->tpmif_list, &tpmif_list);
        num_frontends++;
 
        return tpmif;
+
+ out_of_memory:
+       if (tpmif != NULL) {
+               kfree(tpmif->mmap_pages);
+               kmem_cache_free(tpmif_cachep, tpmif);
+       }
+       printk("%s: out of memory\n", __FUNCTION__);
+       return ERR_PTR(-ENOMEM);
 }
 
 static void free_tpmif(tpmif_t * tpmif)
 {
+       int i;
+
        num_frontends--;
+
        list_del(&tpmif->tpmif_list);
-       balloon_dealloc_empty_page_range(tpmif->pagerange, TPMIF_TX_RING_SIZE);
+
+       for (i = 0; i < TPMIF_TX_RING_SIZE; i++)
+               balloon_free_empty_page(tpmif->mmap_pages[i]);
+       kfree(tpmif->mmap_pages);
+
        kmem_cache_free(tpmif_cachep, tpmif);
 }
 
index 466c3ee581b8d74c002aa7af5f03702a9970c5f2..701a5ad03e38cd948d711e4c4e2fae221e47b15c 100644 (file)
@@ -253,7 +253,7 @@ int _packet_write(struct packet *pak,
                        return 0;
                }
 
-               gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
                                  GNTMAP_host_map, tx->ref, tpmif->domid);
 
                if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
@@ -270,7 +270,7 @@ int _packet_write(struct packet *pak,
 
                tocopy = min_t(size_t, size - offset, PAGE_SIZE);
 
-               if (copy_from_buffer((void *)(MMAP_VADDR(tpmif, i) |
+               if (copy_from_buffer((void *)(idx_to_kaddr(tpmif, i) |
                                              (tx->addr & ~PAGE_MASK)),
                                     &data[offset], tocopy, isuserbuffer)) {
                        tpmif_put(tpmif);
@@ -278,7 +278,7 @@ int _packet_write(struct packet *pak,
                }
                tx->size = tocopy;
 
-               gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i),
                                    GNTMAP_host_map, handle);
 
                if (unlikely
@@ -391,7 +391,7 @@ static int packet_read_shmem(struct packet *pak,
 
                tx = &tpmif->tx->ring[i].req;
 
-               gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
                                  GNTMAP_host_map, tx->ref, tpmif->domid);
 
                if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
@@ -414,10 +414,10 @@ static int packet_read_shmem(struct packet *pak,
                }
 
                DPRINTK("Copying from mapped memory at %08lx\n",
-                       (unsigned long)(MMAP_VADDR(tpmif, i) |
+                       (unsigned long)(idx_to_kaddr(tpmif, i) |
                                        (tx->addr & ~PAGE_MASK)));
 
-               src = (void *)(MMAP_VADDR(tpmif, i) |
+               src = (void *)(idx_to_kaddr(tpmif, i) |
                               ((tx->addr & ~PAGE_MASK) + pg_offset));
                if (copy_to_buffer(&buffer[offset],
                                   src, to_copy, isuserbuffer)) {
@@ -428,7 +428,7 @@ static int packet_read_shmem(struct packet *pak,
                        tpmif->domid, buffer[offset], buffer[offset + 1],
                        buffer[offset + 2], buffer[offset + 3]);
 
-               gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i),
                                    GNTMAP_host_map, handle);
 
                if (unlikely